#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include "server_thread_cliente.h"
#include "server_thread_enviar.h"
#include "server_socket.h"
#include "../Modelo/Partida.h"
#define PORT 4321
#define LARGO 5

using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::stoi;

Server_thread_cliente::Server_thread_cliente(Server_socket* s, Server_socket* nuevo){
	socket = s;
	nuevo_socket = nuevo;
        agregadoAPartida = false;
}

Server_thread_cliente::~Server_thread_cliente(){
}

/* Ejecutar: funcion donde hay un bucle para enviar y recibir informacion del cliente. 
 * Al principio, antes de empezar el juego, solo espera consultas del cliente (como partidas
 * disponibles, etc) y las responde. Luego se crea el jugador y se lo agrega a la lista de jugadores.
 * Finalmente se lanza un hilo para enviar cambios de estado y se usa este hilo para recibir eventos
 * del juego. */
void Server_thread_cliente::ejecutar(){
    /* hilo para enviar datos.*/
//    Server_thread_enviar thread_send = Server_thread_enviar(socket,nuevo_socket);
//    thread_send.setFlagsCorrer(correServer, &correCliente, &agregadoAPartida);
//    thread_send.setTiempoActualizacion(tiempoActualizacion);
//    thread_send.iniciar();    
    /**** BUCLE ANTES DE EMPEZAR EL JUEGO. ****/        
    while (*correServer && correCliente && agregadoAPartida == false){
        // Leer largo de lo recibido (largo establecido en 5 caracteres tipo 00500).
        string largoALeer;			
        int cantbytes;
        if ((cantbytes = socket->recibir(nuevo_socket->get_fd(),&largoALeer, LARGO)) == -1){
            cout<<"server_thread_cliente"<<endl;
        }           
        cout<<"server_thread_cliente-largorecibido: "<<largoALeer;
        int largo = stoi(largoALeer);
        //Leer la cantidad de bytes que dice el largo.
        string buffer;			
        int numbytes;
        if ((numbytes = socket->recibir(nuevo_socket->get_fd(),&buffer, largo)) == -1){
            cout<<"server_thread_cliente recibir"<<endl;
        }
       cout<<"server_thread_cliente-bufferrecibido: "<<buffer;
              
        /* Si recibe comando para crear nueva partida --> envio campañas.*/
        if (buffer[0] == 'C'){
            setNombreJugadorYPartida(buffer);
            int tam = infoCampanias.size();
            if (socket->enviar(nuevo_socket->get_fd(), infoCampanias, tam) == -1){
                cout<<"server_thread_cliente enviar"<<endl;
            }
        } 
        /* Si Recibe id de la campaña que quiere seleccionar --> creo partida con esa campania y la agrego a la lista.
         * agregadoAPartida = true;*/
       else if (buffer[0] == 'N'){
           
       }
       else{ //SOLO PARA PROBAR INTEGRACION
            string aux = "5|hola";
            int aux_tam = aux.size();
            if(socket->enviar(nuevo_socket->get_fd(), aux, aux_tam) == -1){
                cout<<"server_thread_cliente enviar (integracion)"<<endl;
            }
       }
        /* 3) if Recibe comando para unirse a partida --> envio partidas disponibles. 
         * agregar a partida forma de imprimir un string para envio. */
        /* 4) if Recibe id de la partida a la cual quiere unirse.--> lo agrego a la partida.
         * agregadoAPartida = true;*/
        //}
                
        /**** UNA VEZ QUE CREO O SE UNIO A UNA PARTIDA, SE CREA EL JUGADOR Y SE LO AGREGA
         **** A LA LISTA DE JUGADORES.****/
        
    }
    /**** BUCLE PARA RECIBIR EVENTOS DEL JUEGO****/
    while (*correServer && correCliente){
        //Leer largo de lo recibido(largo establecido en 5 caracteres tipo 00500)
        string largoALeer;			
        int cantbytes;
        if ((cantbytes = socket->recibir(nuevo_socket->get_fd(),&largoALeer, LARGO)) == -1){
            cout<<"server_thread_cliente recibir"<<endl;
        }
        largoALeer[cantbytes] = '\0';
        cout<<"server_thread_cliente-largorecibido: "<<largoALeer;
        int largo = atoi(largoALeer.c_str());
        
        //Leer la cantidad de bytes que dice el largo.
        string buffer;			
        int numbytes;
        if ((numbytes = socket->recibir(nuevo_socket->get_fd(),&buffer, largo)) == -1){
            cout<<"server_thread_cliente recibir"<<endl;
        }
        buffer[numbytes] = '\0';
        cout<<"server_thread_cliente-bufferrecibido: "<<buffer;
              
        //Crear Evento (mensaje, jugador).
        //Encolar Evento en la cola de eventos.
        //}
    }        
        // join del hilo de enviar:
	//thread_send.join();	
	// Cerrar socket del cliente.
	nuevo_socket->cerrar();	
}

void Server_thread_cliente::setFlagCorrer(bool* correr){
    correServer = correr;
}

void Server_thread_cliente::setListaPartidas(vector<Partida*> *lista){
    listaPartidas = lista;
}

void Server_thread_cliente::setInfoCampanias(string info){
    infoCampanias = info;
}

void Server_thread_cliente::setTiempoActualizacion(int tiempo){
    tiempoActualizacion = tiempo;
}

void Server_thread_cliente::setListaJugadores(std::vector<Jugador*> *lista){
    listaJugadores = lista;    
}

void Server_thread_cliente::setNombreJugadorYPartida(string buffer){
    //"00032|nombreJugador|nombrePartida"
    string sinLargo = buffer.substr(LARGO + 1); //jugador|partida
    unsigned pos = sinLargo.find("|");         //posicion del pipe.
    nombreJugador = sinLargo.substr(0,pos);
    nombrePartida = sinLargo.substr(pos+1);    
}